'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php',
'Http' => 'includes/HttpFunctions.php',
'Image' => 'includes/Image.php',
+ 'IP' => 'includes/IP.php',
'ThumbnailImage' => 'includes/Image.php',
'ImageGallery' => 'includes/ImageGallery.php',
'ImagePage' => 'includes/ImagePage.php',
*/
function loadRange( $address, $killExpired = true )
{
- $iaddr = wfIP2Hex( $address );
+ $iaddr = IP::ToHex( $address );
if ( $iaddr === false ) {
# Invalid address
return false;
$parts = explode( '/', $range );
if ( count( $parts ) == 2 ) {
$shift = 32 - $parts[1];
- $ipint = wfIP2Unsigned( $parts[0] );
+ $ipint = IP::ToUnsigned( $parts[0] );
$ipint = $ipint >> $shift << $shift;
$newip = long2ip( $ipint );
$range = "$newip/{$parts[1]}";
--- /dev/null
+<?php
+/*
+ * Collection of public static functions to play with IP address
+ * and IP blocks.
+ *
+ * @Author "Ashar Voultoiz" <hashar@altern.org>
+ * @License GPL v2 or later
+ */
+
+// Some regex definition to "play" with IP address and IP address blocks
+
+// An IP is made of 4 bytes from x00 to xFF which is d0 to d255
+define( 'RE_IP_BYTE', '(25[0-5]|2[0-4]\d|1?\d{1,2})');
+define( 'RE_IP_ADD' , RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
+// An IP block is an IP address and a prefix (d1 to d32)
+define( 'RE_IP_PREFIX' , '(3[0-2]|[12]?\d)');
+define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX);
+
+class IP {
+
+ /**
+ * Validate an IP address.
+ * @return boolean True if it is valid.
+ */
+ public static function IsValid( $ip ) {
+ return preg_match( '/^' . RE_IP_ADD . '$/', $ip, $matches) ;
+ }
+
+ /**
+ * Validate an IP Block.
+ * @return boolean True if it is valid.
+ */
+ public static function IsValidBlock( $ipblock ) {
+ return ( count(self::ToArray($ipblock)) == 1 + 5 );
+ }
+
+ /**
+ * Determine if an IP address really is an IP address, and if it is public,
+ * i.e. not RFC 1918 or similar
+ * Comes from ProxyTools.php
+ */
+ function IsPublic( $ip ) {
+ $n = IP::ToUnsigned( $ip );
+ if ( !$n ) {
+ return false;
+ }
+
+ // ip2long accepts incomplete addresses, as well as some addresses
+ // followed by garbage characters. Check that it's really valid.
+ if( $ip != long2ip( $n ) ) {
+ return false;
+ }
+
+ static $privateRanges = false;
+ if ( !$privateRanges ) {
+ $privateRanges = array(
+ array( '10.0.0.0', '10.255.255.255' ), # RFC 1918 (private)
+ array( '172.16.0.0', '172.31.255.255' ), # "
+ array( '192.168.0.0', '192.168.255.255' ), # "
+ array( '0.0.0.0', '0.255.255.255' ), # this network
+ array( '127.0.0.0', '127.255.255.255' ), # loopback
+ );
+ }
+
+ foreach ( $privateRanges as $r ) {
+ $start = IP::ToUnsigned( $r[0] );
+ $end = IP::ToUnsigned( $r[1] );
+ if ( $n >= $start && $n <= $end ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Split out an IP block as an array of 4 bytes and a mask,
+ * return false if it cant be determined
+ *
+ * @parameter $ip string A quad dotted IP address
+ * @return array
+ */
+ public static function ToArray( $ipblock ) {
+ if(! preg_match( '/^' . RE_IP_ADD . '(?:\/(?:'.RE_IP_PREFIX.'))?' . '$/', $ipblock, $matches ) ) {
+ return false;
+ } else {
+ return $matches;
+ }
+ }
+
+ /**
+ * Return a zero-padded hexadecimal representation of an IP address
+ * Comes from ProxyTools.php
+ * @param $ip Quad dotted IP address.
+ */
+ public static function ToHex( $ip ) {
+ $n = self::ToUnsigned( $ip );
+ if ( $n !== false ) {
+ $n = sprintf( '%08X', $n );
+ }
+ return $n;
+ }
+
+ /**
+ * Given an IP address in dotted-quad notation, returns an unsigned integer.
+ * Like ip2long() except that it actually works and has a consistent error return value.
+ * Comes from ProxyTools.php
+ * @param $ip Quad dotted IP address.
+ */
+ public static function ToUnsigned( $ip ) {
+ $n = ip2long( $ip );
+ if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
+ $n = false;
+ } elseif ( $n < 0 ) {
+ $n += pow( 2, 32 );
+ }
+ return $n;
+ }
+}
+?>
# Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private)
foreach ( $ipchain as $i => $curIP ) {
if ( array_key_exists( $curIP, $trustedProxies ) ) {
- if ( isset( $ipchain[$i + 1] ) && wfIsIPPublic( $ipchain[$i + 1] ) ) {
+ if ( isset( $ipchain[$i + 1] ) && IP::IsPublic( $ipchain[$i + 1] ) ) {
$ip = $ipchain[$i + 1];
}
} else {
return $ip;
}
-/**
- * Given an IP address in dotted-quad notation, returns an unsigned integer.
- * Like ip2long() except that it actually works and has a consistent error return value.
- */
-function wfIP2Unsigned( $ip ) {
- $n = ip2long( $ip );
- if ( $n == -1 || $n === false ) { # Return value on error depends on PHP version
- $n = false;
- } elseif ( $n < 0 ) {
- $n += pow( 2, 32 );
- }
- return $n;
-}
-
-/**
- * Return a zero-padded hexadecimal representation of an IP address
- */
-function wfIP2Hex( $ip ) {
- $n = wfIP2Unsigned( $ip );
- if ( $n !== false ) {
- $n = sprintf( '%08X', $n );
- }
- return $n;
-}
-
-/**
- * Determine if an IP address really is an IP address, and if it is public,
- * i.e. not RFC 1918 or similar
- */
-function wfIsIPPublic( $ip ) {
- $n = wfIP2Unsigned( $ip );
- if ( !$n ) {
- return false;
- }
-
- // ip2long accepts incomplete addresses, as well as some addresses
- // followed by garbage characters. Check that it's really valid.
- if( $ip != long2ip( $n ) ) {
- return false;
- }
-
- static $privateRanges = false;
- if ( !$privateRanges ) {
- $privateRanges = array(
- array( '10.0.0.0', '10.255.255.255' ), # RFC 1918 (private)
- array( '172.16.0.0', '172.31.255.255' ), # "
- array( '192.168.0.0', '192.168.255.255' ), # "
- array( '0.0.0.0', '0.255.255.255' ), # this network
- array( '127.0.0.0', '127.255.255.255' ), # loopback
- );
- }
-
- foreach ( $privateRanges as $r ) {
- $start = wfIP2Unsigned( $r[0] );
- $end = wfIP2Unsigned( $r[1] );
- if ( $n >= $start && $n <= $end ) {
- return false;
- }
- }
- return true;
-}
-
/**
* Forks processes to scan the originating IP for an open proxy server
* MemCached can be used to skip IPs that have already been scanned
if ( count( $parts ) != 2 ) {
return array( false, false );
}
- $network = wfIP2Unsigned( $parts[0] );
+ $network = IP::ToUnsigned( $parts[0] );
if ( $network !== false && is_numeric( $parts[1] ) && $parts[1] >= 0 && $parts[1] <= 32 ) {
$bits = $parts[1];
} else {
require_once( "$IP/includes/MessageCache.php" );
require_once( "$IP/includes/Parser.php" );
require_once( "$IP/includes/LoadBalancer.php" );
+require_once( "$IP/includes/IP.php" );
require_once( "$IP/includes/ProxyTools.php" );
require_once( "$IP/includes/ObjectCache.php" );
require_once( "$IP/includes/ImageFunctions.php" );
// No extra conditions
} elseif ( substr( $this->ip, 0, 1 ) == '#' ) {
$conds['ipb_id'] = substr( $this->ip, 1 );
- } elseif ( wfIP2Unsigned( $this->ip ) !== false ) {
+ } elseif ( IP::ToUnsigned( $this->ip ) !== false ) {
$conds['ipb_address'] = $this->ip;
$conds['ipb_auto'] = 0;
} elseif( preg_match( "/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\\/(\\d{1,2})$/", $this->ip, $matches ) ) {